#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "kv.h"
kv_pair *kv_add(kv_pair *kv,const char *key,const char *value) {
    kv_pair *first_kv=kv,*pre_kv;
    while (kv) {
        pre_kv=kv;
        kv=kv->next;
    } 

    kv=malloc(sizeof(kv_pair));
    kv->key=malloc(strlen(key)+1);
    kv->value=malloc(strlen(value)+1);
    strcpy(kv->key,(char *)key);
    strcpy(kv->value,(char *)value);

    kv->next=NULL;
    if (first_kv) {
        kv->first=first_kv;
        pre_kv->next=kv;
    } else {
        kv->first=kv;
    }
    return kv->first;
}
kv_pair *kv_remove(kv_pair *kv,const char *key) {
    kv_pair *pre_one=NULL;
    while (kv) {
        if (!strcmp(kv->key,key)) {
            if (pre_one) {
                pre_one->next=kv->next;
                free(kv->key);
                free(kv->value);
                free(kv);
                if (pre_one->next) {
                    kv=pre_one->next;
                    continue;
                } else {
                    break;
                }
            }
            continue;
        }
        pre_one=kv;
        kv=kv->next;
    }
    return pre_one->first;
}
kv_pair *kv_get_by_key(kv_pair *kv,const char *key) {
    kv_pair *ret_kv=NULL;
    while (kv) {
        if (!strcmp(kv->key,key)) {
            ret_kv=kv_add(ret_kv,key,kv->value);
        }
        kv=kv->next;
    }
    return ret_kv;
}
char *kv_join(kv_pair *kv,const char *kv_delimiter,const char *pair_delimiter) {
    char *join_string=NULL; 
    uint16_t pd_len=strlen(pair_delimiter);
    uint16_t kvd_len=strlen(kv_delimiter);
    uint16_t str_len=0;

    while (kv) {
        if (join_string) {
            str_len+=strlen(kv->key)+strlen(kv->value)+pd_len+kvd_len;
            join_string=realloc(join_string,str_len);
            strcat(join_string,pair_delimiter);
        } else {
            str_len+=strlen(kv->key)+strlen(kv->value)+kvd_len;
            join_string=malloc(str_len);
        }
        strcat(join_string,kv->key);
        strcat(join_string,kv_delimiter);
        strcat(join_string,kv->value);
        kv=kv->next;
    }
    join_string=realloc(join_string,str_len+1);
    join_string[str_len]=0;
    return join_string;
}
bool kv_free(kv_pair *kv) {
    kv_pair *current_kv;
    while (kv) {
        current_kv=kv;
        kv=kv->next;
        free(current_kv->key);
        free(current_kv->value);
        free(current_kv);
    }
    return true;
}
